package com.cy.pj.sys.common.aspect;

import com.cy.pj.sys.common.annotation.RequiredLog;
import com.cy.pj.sys.common.utils.IPUtils;
import com.cy.pj.sys.pojo.SysLog;
import com.cy.pj.sys.service.SysLogService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
public class SysLogAspect {
    @Autowired
    private SysLogService sysLogService;
    private Logger log = LoggerFactory.getLogger(SysLogAspect.class);
    //切入点
    @Pointcut("@annotation(com.cy.pj.sys.common.annotation.RequiredLog)")
    public void doLog() {
        
    }

    //环绕增强
    @Around("doLog()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();
        long time = end - start;
        log.info("方法执行的总时长为：" + time);
        saveSysLog(joinPoint, time);
        return result;
    }
    //保存日志的方法
    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) throws NoSuchMethodException, JsonProcessingException {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Class<?> targetClass = joinPoint.getTarget().getClass();
        String className = targetClass.getName();
        String methodName = signature.getMethod().getName();
        Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
        Method targetMethod = targetClass.getDeclaredMethod(methodName, parameterTypes);
        String username = "测试用用户名";
        //获取方法参数
        Object[] args = joinPoint.getArgs();
        System.out.println("paramsObj=" + args);

        String params = new ObjectMapper().writeValueAsString(args);
        //封装实体
        SysLog sysLog = new SysLog();
        sysLog.setUsername(username);
//        获取注解上定义的value值作为操作值

        RequiredLog declaredAnnotation = targetMethod.getDeclaredAnnotation(RequiredLog.class);
        if (declaredAnnotation != null) {
            sysLog.setOperation(declaredAnnotation.value());
        }
        sysLog.setMethod(className + "." + methodName);
        sysLog.setParams(params);
        sysLog.setTime(time);
        sysLog.setCreateDate(new Date());
        sysLog.setIp(IPUtils.getIpAddr());
        sysLogService.insertObject(sysLog);

    }


}
